#!/usr/bin/env bash
# shellcheck disable=SC2034  # Unused variables OK as this script is `source`d.

set -o xtrace
set -o errexit
set -o nounset
set -o pipefail

# Set the default Rust log level to info if unset.
# https://docs.rs/env_logger
export RUST_LOG="${RUST_LOG:-info}"

# See https://pantheon.corp.google.com/artifacts/docker/oak-ci/europe-west2/oak-development?project=oak-ci
readonly DOCKER_IMAGE_NAME='europe-west2-docker.pkg.dev/oak-ci/oak-development/oak-development:latest'

# The difference between Docker image id and image digest is that the image id corresponds to the
# hash of the contents of the image, while the image digest is a hash of the image and its metadata,
# and it is assigned by the specific registry after pushing the image there. Therefore, we should
# mostly rely on the image id locally, though we need to use the image digest when pulling the image
# from a registry first.

# Do not modify manually. This value is automatically updated by ./scripts/docker_build .
readonly DOCKER_IMAGE_ID='sha256:0eaee35dde1820758b59c6c92069e1b23f236d74120e19168134380cd4e97f7b'

# Do not modify manually. This value is automatically updated by ./scripts/docker_push .
readonly DOCKER_IMAGE_REPO_DIGEST='europe-west2-docker.pkg.dev/oak-ci/oak-development/oak-development@sha256:59f3914b8237601bcacdb6ba86c6aebe9f5fcc49c9ed377e281ed1e852bc7faa'

readonly CACHE_DIR='bazel-cache'
readonly SERVER_BIN_DIR="${PWD}/oak_loader/bin"

# To set up remote cache write credentials:
# - navigate to https://pantheon.corp.google.com/iam-admin/serviceaccounts?project=oak-ci
# - click on "Create Service Account"
#   + use your @google.com username as the service account name (e.g. "tzn")
#   + leave the service account ID as is (e.g. "tzn-110")
#   + leave the service account description empty
# - grant the "Storage Object Admin" role to the newly created account
# - click on "Create Key", then select "JSON"
# - save the generated key as the file referenced below, within the project directory
#   + make sure to not check it in to git, check your `.gitignore` configuration
readonly OAK_REMOTE_CACHE_KEY='./.oak_remote_cache_key.json'

(
  # Disable xtrace to avoid leaking secrets in logs.
  set +o xtrace;
  # Do we have a JSON key for the remote cache.
  # https://docs.bazel.build/versions/master/remote-caching.html#google-cloud-storage
  if [[ ! -f "$OAK_REMOTE_CACHE_KEY" ]]; then
    # Check if this exists in the environment and it is not empty.
    if [[ -n "${BAZEL_GOOGLE_CREDENTIALS:-}" ]]; then
      echo "$BAZEL_GOOGLE_CREDENTIALS" > "$OAK_REMOTE_CACHE_KEY"
    fi
  fi
)

declare -a bazel_build_flags

# Use the remote cache, assuming it is publicly readable.
# See https://pantheon.corp.google.com/storage/browser/oak-bazel-cache?project=oak-ci
bazel_build_flags+=(
  '--remote_cache=https://storage.googleapis.com/oak-bazel-cache'
  # Fail immediately if the Bazel server lock cannot be acquired so that we can notice this in CI
  # and avoid attempting to parallelize steps that are actually serialized by Bazel.
  '--block_for_lock=false'
  # Useful to determine how long individual steps are taking in CI.
  '--show_timestamps'
)

# If we now have a key file, use it, otherwise disable uploading artifacts to remote cache.
# Note that this is only needed to write to the cache, not to read from it.
if [[ -f "$OAK_REMOTE_CACHE_KEY" ]]; then
  bazel_build_flags+=(
    "--google_credentials=$OAK_REMOTE_CACHE_KEY"
  )
else
  bazel_build_flags+=(
    '--remote_upload_local_results=false'
  )
fi

declare -a cargo_build_flags

cargo_build_flags+=(
  '--release'
)

if [[ "${OSTYPE}" == "darwin"*  ]]; then
  bazel_build_flags+=( '--config=darwin' )
else
  # The -linux-musl target is the officially supported way of producing fully
  # static binaries from a Rust program.  However, musl is explicitly built
  # on the Linux syscalll layer, and so is not available on macOS.
  cargo_build_flags+=(
    '--target=x86_64-unknown-linux-musl'
  )
fi

if [[ "${OSTYPE}" == "darwin"*  ]]; then
  readonly RUST_HOST_TARGET="${RUST_HOST_TARGET:-x86_64-apple-darwin}"
else
  readonly RUST_HOST_TARGET="${RUST_HOST_TARGET:-x86_64-unknown-linux-gnu}"
fi
